//
//  SFCFileSetUpHelper.h
//  SVNForCocoa
//
//  Created by Jeremy Pereira on 11/11/2013.
//  Copyright (c) 2013 Jeremy Pereira. All rights reserved.
//
/*!
 *    @brief Declarations associated with SFCFileSetUpHelper
 */
#import <Foundation/Foundation.h>

/*!
 *    @brief The location of the svn command.
 *
 *    Absolute path to svn.  Assumes that it is a Mac Ports command installed in
 *    <tt>/opt/local/bin</tt>
 */
extern NSString* const SVN_CMD;
/*!
 *    @brief A helper class to manipulate files needed for testing including
 *           a repository etc.
 *
 *    This class can be used to create repos and working copies using the svn
 *    command line tools.  It maintains its own working copy at 
 *    [self rootPath]/.fsu/wc for manipulating the repo without affecting the
 *    official test working copy.
 */
@interface SFCFileSetUpHelper : NSObject

/*!
 *    @brief Init with the given folder for test files.
 *
 *    <p>Note that the passed in folder always has ".testFiles" appended to it to
 *    create the acrtual directory.  This is a safety feature in case, somebody
 *    passes in "." or "/".
 *    </p><p>
 *    Note that because this class is designed for use in unit tests and the 
 *    things it does are not supposed to fail, several of its methods will 
 *    throw exceptions, if they break for issues that should be handled in
 *    production code.  e.g. if you don't have permission to write to the 
 *    current directory.
 *
 *    @param folderPath folder path.  The actual folder will be named
 *            <tt><folderpath>.testfiles</tt>
 *
 *    @return A new SFCFileSetUpHelper
 */
-(id) initWithFolder: (NSString*) folderPath;

/*!
 *    @brief Relative path of the root folder for the test files.
 */
@property (nonatomic, readonly, copy) NSString* rootPath;
/*!
 *    @brief Where the working copy is (relative path to CWD)
 */
@property (nonatomic, readonly, copy) NSString* wcPath;
/*!
 *    @brief Where the repository is (relative path to CWD)
 */
@property (nonatomic, readonly, copy) NSString* repoPath;
/*!
 *    @brief Absolute URI of the repo using file scheme.
 */
@property (nonatomic, readonly, copy) NSURL* repoURI;
/*!
 *    @brief Absolute URI of the repo using svn scheme.
 */
@property (nonatomic, readonly, copy) NSURL* svnServeURI;

/*!
 *    @brief Delete everything and recreate the test directory and an empty
 *           repository.
 */
-(void) resetFiles;

/*!
 *    @brief Add a file to the repository.
 *
 *    Adds the given file to the repository.  Will throw an exception if it 
 *    can't be done.
 *
 *    @param fileName file to add, relative to repository root.
 *    @param content  What to put in the file.
 */
-(void) addFileToRepository: (NSString*) fileName content: (NSString*) content;

/*!
 *    @brief Amend and commit a file in repo.
 *
 *    Will throw an exception if anything goes wrong.
 *
 *    @param fileName File to amend.  It must already exist in the repository.
 *    @param content  Content that will be appended to the file.
 */
-(void) updateFileInRepository: (NSString*) fileName
                 appendContent: (NSString*) content;

/*!
 *    @brief Checkout the repo to the working copy.
 */
-(void) checkoutWc;

/*!
 *    @brief Append some text to a given file in the working copy.
 *
 *    Will throw an exception if anything breaks e.g. the file is missing.
 *
 *    @param content  Content to append.
 *    @param fileName The file name in the working copy.
 */
-(void) append: (NSString*) content toFileInWc: (NSString*) fileName;

/*!
 *    @brief Append some txt to a given file on the file system.
 *
 *    Will throw an exception if anything breaks e.g. the file is missing.
 *
 *    @param content  Content t put in the file.
 *    @param fileName An arbitrary filepath
 */
-(void) append: (NSString*) content toFile: (NSString*) fileName;


/*!
 *    @brief Start an svnserve with its root as the repo.
 *
 *    Will throw an exception if anything goes wrong.
 */
-(void) startServer;
/*!
 *    @brief Stop the svnserve server.
 *
 *    Is silently ignored if the svnserve server is not running.
 */
-(void) stopServer;

-(void) writeRepoConfig: (NSString*) configContent;
-(void) writePasswords: (NSString*) passwords;

/*!
 *    @brief Test the svn status of a file.
 *
 *    Runs an svn status and checks that the output starts with the supplied
 *    status string.  e.g. "A" means add, "?" means unversioned, " M" means
 *    properties modified.
 *
 *    @param filePath File to check.
 *    @param status   Status to check for.
 *
 *    @return true if the file is in the given status.
 */
-(bool) file: (NSString*) filePath statusIs: (NSString*) status;

/*!
 *    @brief Get the size of the given file in bytes.
 *
 *    @param file File to get the size of.
 *
 *    @return The size of the file.  Will return 0 if the file does not exist.
 */
-(size_t) sizeOfFile: (NSString*) file;

/*!
 *    @brief Run an external task with the given arguments.
 *
 *    Runs a task as a separate process.  The exit status, stderr and stdout are
 *    all thrown away.  This method throws an exception if it all goes wrong.
 *
 *    @param taskPath  Path to command.
 *    @param arguments Arguments of command (exclude the command itself).
 */
-(void) runTask: (NSString*) taskPath withArguments: (NSArray*) arguments;
/*!
 *    @brief Get the std out from running a task.
 *
 *    Runs a task as a separate process.  The exit status and stderr are
 *    thrown away.  This method throws an exception if it all goes wrong.
 *
 *    @param taskPath  path to command to run.
 *    @param arguments Arguments of command (exclude the command itself).
 *
 *    @return A string containing the standard output of the task.
 */
-(NSString*) outputOfTask: (NSString*) taskPath
            withArguments: (NSArray*) arguments;

/*!
 *    @brief Makes sure the file exists.
 *
 *    This gurantees the file's existance.
 *
 *    @param aFile File to ensure exists.
 */
-(void) touch: (NSString*) aFile;


@end
